/*
 ***************************************************************************
 * MediaTeK Inc.
 * 4F, No. 2 Technology	5th	Rd.
 * Science-based Industrial	Park
 * Hsin-chu, Taiwan, R.O.C.
 *
 * (c) Copyright 2002-2012, MTK.
 *
 * All rights reserved.	MediaTeK's source	code is	an unpublished work	and	the
 * use of a	copyright notice does not imply	otherwise. This	source code
 * contains	confidential trade secret material of MediaTeK Tech. Any attemp
 * or participation	in deciphering,	decoding, reverse engineering or in	any
 * way altering	the	source code	is stricitly prohibited, unless	the	prior
 * written consent of MediaTeK, Inc. is obtained.
 ***************************************************************************

	Module Name:
	omci_me_layer2_data_services_func.c

	Abstract:

	Revision History:
	Who			When			What
	--------	----------		----------------------------------------------
	Name		Date			Modification logs
	lisa.xue	2012/7/28	Create
*/

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <memory.h>
#include "omci_adpt_common.h"
#include "omci_me_mac_bridge.h"
#include "omci_me_layer2_data_services.h"
#include "blapi_traffic.h"


#define UPDATE_RULE_FOR_GPON_ICMPV6		0
#define ADD_EBT_CHAIN_FOR_GPON_ICMPV6	1
#define DEL_EBT_CHAIN_FOR_GPON_ICMPV6	2
#define GPON_ICMPV6_SH_EBT				"/tmp/etc/gpon_icmpv6_ebt.sh"

#define LAN_INTERFACE 						0
#define WAN_INTERFACE 						1

#define ICMPV6_ERROR_MSG_ATTR				1
#define ICMPV6_INFO_MSG_ATTR				2
#define ICMPV6_RS_MSG_ATTR					3
#define ICMPV6_MLD_MSG_ATTR				8
#define ICMPV6_UNKNOWN_MSG_ATTR			9

int icmpv6Type[6] = {133, 134, 135, 136, 137, 130};



/*******************************************************************************************************************************
9.3.18 Dot1 rate limiter

********************************************************************************************************************************/

attribute_func_t Dot1RateLimiterTPTypeFunc = {
	NULL,
	setDot1RateLimiterTPType
};

omci_attr_dscp_t omci_attr_dot1_rate_limit_op[]={
{0, "meId",								2,  ATTR_ACCESS_R_SET_CREATE,       ATTR_FORMAT_UNSIGNED_INT,   ATTR_FULLY_SUPPORT,	&generalAttrFunc},
{1, "parent me pointer",				2,  ATTR_ACCESS_R_W_SET_CREATE,     ATTR_FORMAT_POINTER,        ATTR_FULLY_SUPPORT,	&generalAttrFunc},
{2, "tp type",							1,  ATTR_ACCESS_R_W_SET_CREATE,     ATTR_FORMAT_ENUM,           ATTR_FULLY_SUPPORT,	&Dot1RateLimiterTPTypeFunc},
{3, "us unicast flood rate ptr",		2,  ATTR_ACCESS_R_W_SET_CREATE,     ATTR_FORMAT_POINTER,        ATTR_FULLY_SUPPORT,	&generalAttrFunc},
{4, "us broadcast rate ptr",			2,  ATTR_ACCESS_R_W_SET_CREATE,     ATTR_FORMAT_POINTER,        ATTR_FULLY_SUPPORT,	&generalAttrFunc},
{5, "us multicast payload rate ptr",	2,  ATTR_ACCESS_R_W_SET_CREATE,     ATTR_FORMAT_POINTER,        ATTR_FULLY_SUPPORT,	&generalAttrFunc},
{255, "", 								0, 	0, 	0, 	0, 	NULL}
};

omci_me_func_t omci_me_dot1_rate_limit_op ={
	omci_me_general_create_op,
	omci_me_general_delete_op,
	omci_me_general_set_op,
	omci_me_general_get_op,
};

omci_dot1_rate_limit_t omci_dot1_rate_limit_attr_data = {0};

omci_attr_t omci_dot1_rate_limit_attr ={
	(uint8_t *)&omci_dot1_rate_limit_attr_data,
	sizeof(omci_dot1_rate_limit_attr_data)
};

#ifdef TCSUPPORT_OMCI_DOT1AG
/*******************************************************************************************************************************
9.3.19 Dot1ag maintenance domain

********************************************************************************************************************************/

static attribute_func_t dot1agMaintenanceDomainMDLevelFunc = {
	NULL,
	setDot1agMaintenanceDomainMDLevel
};

static attribute_func_t dot1agMaintenanceDomainMDNameFormatFunc = {
	NULL,
	setDot1agMaintenanceDomainMDNameFormat
};

static attribute_func_t dot1agMaintenanceDomainMDName1Func = {
	NULL,
	NULL
};

static attribute_func_t dot1agMaintenanceDomainMDName2Func = {
	NULL,
	NULL
};

static attribute_func_t dot1agMaintenanceDomainMHFCreationFunc = {
	NULL,
	setDot1agMaintenanceDomainMHFCreation
};

static attribute_func_t dot1agMaintenanceDomainSenderIDPermissionFunc = {
	NULL,
	setDot1agMaintenanceDomainSenderIDPermission
};

omci_attr_dscp_t omci_attr_dot1ag_maint_domain_op[]={
{0, "meId",						2,  ATTR_ACCESS_R_SET_CREATE,       ATTR_FORMAT_UNSIGNED_INT,   ATTR_FULLY_SUPPORT,&generalAttrFunc},
{1, "MD level",					1,  ATTR_ACCESS_R_W_SET_CREATE,     ATTR_FORMAT_UNSIGNED_INT,   ATTR_FULLY_SUPPORT,&dot1agMaintenanceDomainMDLevelFunc},
{2, "MD name format",			1,  ATTR_ACCESS_R_W_SET_CREATE,     ATTR_FORMAT_ENUM,           ATTR_FULLY_SUPPORT,&dot1agMaintenanceDomainMDNameFormatFunc},
{3, "MD name 1",				25, ATTR_ACCESS_R_W,                ATTR_FORMAT_STRING,         ATTR_FULLY_SUPPORT,&dot1agMaintenanceDomainMDName1Func},
{4, "MD name 2",				25, ATTR_ACCESS_R_W,                ATTR_FORMAT_STRING,         ATTR_FULLY_SUPPORT,&dot1agMaintenanceDomainMDName2Func},
{5, "MHF creation",				1,  ATTR_ACCESS_R_W_SET_CREATE,     ATTR_FORMAT_ENUM,           ATTR_FULLY_SUPPORT,&dot1agMaintenanceDomainMHFCreationFunc},
{6, "sender id permission",		1,  ATTR_ACCESS_R_W_SET_CREATE,     ATTR_FORMAT_ENUM,           ATTR_FULLY_SUPPORT,&dot1agMaintenanceDomainSenderIDPermissionFunc},
{255, "",						0, 	0, 	0, 	0, 		NULL}
};

omci_me_func_t omci_me_dot1ag_maint_domain_op ={
	omci_me_general_create_op,
	omci_me_general_delete_op,
	omci_me_general_set_op,
	omci_me_general_get_op,
};

omci_dot1ag_maint_domain_t omci_dot1ag_maint_domain_attr_data = {0};

omci_attr_t omci_dot1ag_maint_domain_attr ={
	(uint8_t *)&omci_dot1ag_maint_domain_attr_data,
	sizeof(omci_dot1ag_maint_domain_attr_data)
};


/*******************************************************************************************************************************
9.3.20 Dot1ag maintenance association

********************************************************************************************************************************/

static attribute_func_t dot1agMaintenanceDomainMANameFormatFunc = {
	NULL,
	setDot1agMaintenanceDomainMANameFormat
};

static attribute_func_t dot1agMaintenanceAssociationShortMAName1Func = {
	NULL,
	NULL
};

static attribute_func_t dot1agMaintenanceAssociationShortMAName2Func = {
	NULL,
	NULL
};

static attribute_func_t dot1agMaintenanceAssociationCCMIntervalFunc = {
	NULL,
	NULL
};

static attribute_func_t dot1agMaintenanceAssociationAssociatedVlansFunc = {
	NULL,
	NULL
};


static attribute_func_t dot1agMaintenanceAssociationMHFCreationFunc = {
	NULL,
	setDot1agMaintenanceAssociationMHFCreation
};

static attribute_func_t dot1agMaintenanceAssociationSenderIDPermissionFunc = {
	NULL,
	setDot1agMaintenanceAssociationSenderIDPermission
};

omci_attr_dscp_t omci_attr_dot1ag_maint_associat_op[]={
{0, "meId",						2,  ATTR_ACCESS_R_SET_CREATE,       ATTR_FORMAT_UNSIGNED_INT,   ATTR_FULLY_SUPPORT,&generalAttrFunc},
{1, "MD pointer",				2,  ATTR_ACCESS_R_W_SET_CREATE,     ATTR_FORMAT_POINTER,        ATTR_FULLY_SUPPORT,&generalAttrFunc},
{2, "short MA name format",		1,  ATTR_ACCESS_R_W_SET_CREATE,     ATTR_FORMAT_ENUM,           ATTR_FULLY_SUPPORT,&dot1agMaintenanceDomainMANameFormatFunc},
{3, "short MA name 1",			25, ATTR_ACCESS_R_W,                ATTR_FORMAT_STRING,         ATTR_FULLY_SUPPORT,	&dot1agMaintenanceAssociationShortMAName1Func},
{4, "short MA name 2",			25, ATTR_ACCESS_R_W,                ATTR_FORMAT_STRING,         ATTR_FULLY_SUPPORT,	&dot1agMaintenanceAssociationShortMAName2Func},
{5, "CCM interval",				1,  ATTR_ACCESS_R_W_SET_CREATE,     ATTR_FORMAT_ENUM,           ATTR_FULLY_SUPPORT,&dot1agMaintenanceAssociationCCMIntervalFunc},
{6, "associated vlans",			24, ATTR_ACCESS_R_W,                ATTR_FORMAT_STRING,         ATTR_FULLY_SUPPORT,	&dot1agMaintenanceAssociationAssociatedVlansFunc},
{7, "MHF creation",				1,  ATTR_ACCESS_R_W_SET_CREATE,     ATTR_FORMAT_ENUM,           ATTR_FULLY_SUPPORT,&dot1agMaintenanceAssociationMHFCreationFunc},
{8, "sender id permission",		1,  ATTR_ACCESS_R_W_SET_CREATE,     ATTR_FORMAT_ENUM,           ATTR_FULLY_SUPPORT,&dot1agMaintenanceAssociationSenderIDPermissionFunc},
{255, "", 						0, 	0, 0, 0, NULL}
};

omci_me_func_t omci_me_dot1ag_maint_associat_op ={
	omci_me_general_create_op,
	omci_me_general_delete_op,
	omci_me_general_set_op,
	omci_me_general_get_op,
};

omci_dot1ag_maint_associat_t omci_dot1ag_maint_associat_attr_data = {0};

omci_attr_t omci_dot1ag_maint_associat_attr ={
	(uint8_t *)&omci_dot1ag_maint_associat_attr_data,
	sizeof(omci_dot1ag_maint_associat_attr_data)
};

#endif


/*******************************************************************************************************************************
9.3.32 Ethernet frame extended PM

********************************************************************************************************************************/
omci_attr_dscp_t omci_attr_eth_frame_ext_pm_op[]={
{0,   "meId",					     2, ATTR_ACCESS_R_SET_CREATE,   ATTR_FORMAT_UNSIGNED_INT,   ATTR_FULLY_SUPPORT,&generalAttrFunc},
{1,   "interval end time",	         1, ATTR_ACCESS_R,              ATTR_FORMAT_UNSIGNED_INT,   ATTR_FULLY_SUPPORT,&generalAttrFunc},
{2,   "control block",    	         16,ATTR_ACCESS_R_W_SET_CREATE, ATTR_FORMAT_STRING,   		ATTR_FULLY_SUPPORT,&generalAttrFunc},
{3,   "drop events",		         4, ATTR_ACCESS_R,              ATTR_FORMAT_UNSIGNED_INT,   ATTR_FULLY_SUPPORT,&generalAttrFunc},
{4,   "octets",    		             4, ATTR_ACCESS_R,              ATTR_FORMAT_UNSIGNED_INT,   ATTR_FULLY_SUPPORT,&generalAttrFunc},
{5,   "frames",				         4, ATTR_ACCESS_R,              ATTR_FORMAT_UNSIGNED_INT,   ATTR_FULLY_SUPPORT,&generalAttrFunc},
{6,   "broadcast frames",		     4, ATTR_ACCESS_R,              ATTR_FORMAT_UNSIGNED_INT,   ATTR_FULLY_SUPPORT,&generalAttrFunc},
{7,   "multicast frames", 	         4, ATTR_ACCESS_R,              ATTR_FORMAT_UNSIGNED_INT,   ATTR_FULLY_SUPPORT,&generalAttrFunc},
{8,   "crc errored frames", 	     4, ATTR_ACCESS_R,              ATTR_FORMAT_UNSIGNED_INT,   ATTR_FULLY_SUPPORT,&generalAttrFunc},	
{9,   "undersize frames", 	         4, ATTR_ACCESS_R,              ATTR_FORMAT_UNSIGNED_INT,   ATTR_FULLY_SUPPORT,&generalAttrFunc},
{10,  "oversize frames", 	         4, ATTR_ACCESS_R,              ATTR_FORMAT_UNSIGNED_INT,   ATTR_FULLY_SUPPORT,&generalAttrFunc},
{11,  "frames 64 octets",	         4, ATTR_ACCESS_R,              ATTR_FORMAT_UNSIGNED_INT,   ATTR_FULLY_SUPPORT,&generalAttrFunc},
{12,  "frames 65 to 127 octets",	 4, ATTR_ACCESS_R,              ATTR_FORMAT_UNSIGNED_INT,   ATTR_FULLY_SUPPORT,&generalAttrFunc},
{13,  "frames 128 to 255 octets",	 4, ATTR_ACCESS_R,              ATTR_FORMAT_UNSIGNED_INT,   ATTR_FULLY_SUPPORT,&generalAttrFunc},
{14,  "frames 256 to 511 octets",	 4, ATTR_ACCESS_R,              ATTR_FORMAT_UNSIGNED_INT,   ATTR_FULLY_SUPPORT,&generalAttrFunc},
{15,  "frames 512 to 1023 octets",   4, ATTR_ACCESS_R,              ATTR_FORMAT_UNSIGNED_INT,   ATTR_FULLY_SUPPORT,&generalAttrFunc},
{16,  "frames 1024 to 1518 octets",  4, ATTR_ACCESS_R,              ATTR_FORMAT_UNSIGNED_INT,   ATTR_FULLY_SUPPORT,&generalAttrFunc},
{255, "",                            0, 0, 0, 0, NULL}
};

int get_eth_frame_extend_data(extend_pm_ctrl_block_t ctrl_block, EthFramePmStreamCounters_t *data)
{
	uint8_t validPortId = 0;
	uint8_t direction = 0;
	uint16_t global_disable_accu = 0;
	ECNT_TRAFFIC_WAN_RX_STATISTICS gdma2StatsRx = {0};
	ECNT_TRAFFIC_WAN_TX_STATISTICS gdma2StatsTx = {0};

	if(data == NULL)
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]  pointer is NULL fail\n",__FUNCTION__,__LINE__);
        return -1;
    }
    global_disable_accu = ctrl_block.accumulation_disable & 0x4000;
    direction = (ctrl_block.control_field & 0x0002) >> 1; /*1:downstream, 0:upstream*/
    omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d]  control_field=%02x\n",__FUNCTION__,__LINE__,ctrl_block.control_field);

    if(global_disable_accu)
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]->disable class ME = %d instId = 0x%x accumulation.\n",__FUNCTION__,__LINE__, 
                                                    ctrl_block.parent_me_classId, ctrl_block.parent_me_instId);
        return -1;
    }

    switch(ctrl_block.parent_me_classId)
    {/*ignore ME(98) physical path termination point xDSL UNI part 1
             ignore ME(162) physical path termination point MoCA UNI*/
        case OMCI_CLASS_ID_MAC_BRIDGE_CON_DATA:
        case OMCI_CLASS_ID_MAC_BRIDGE_PORT_CON_DATA:
        case OMCI_CLASS_ID_GEM_INTERWORK_TP:
        case OMCI_CLASS_ID_MULTICAST_GEM_INTERWORK_TP:
        	omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]->unsupported parent class ME %d.\n",__FUNCTION__,__LINE__, ctrl_block.parent_me_classId);
        	break; /*unsupported*/
        case OMCI_CLASS_ID_VIRTUAL_ETHERNET_INTERFACE_POINT:
        	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d] get VEIP Cnt, direction=%d\n",__FUNCTION__,__LINE__,direction);
        	if(direction){
        		if(blapi_traffic_get_wan_rx_statistics(&gdma2StatsRx)!= 0){
        			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d] fe_lib_get_gdma2_rx_statistics fail\n",__FUNCTION__,__LINE__);
        			return -1;
        		}
        		data->dropEvents	= gdma2StatsRx.drop_cnt;
        		data->octets		= gdma2StatsRx.frame_len;
        		data->packets		= gdma2StatsRx.frame_cnt;
        		data->broadcastPkts 	= gdma2StatsRx.broadcast;
        		data->multicastPkts 	= gdma2StatsRx.multicast;
        		data->crcErroredPkts	= gdma2StatsRx.crc;
        		data->undersizePkts 	= gdma2StatsRx.undersize;
        		data->oversizePkts	= gdma2StatsRx.oversize;
        		data->pkts64Octets	= gdma2StatsRx.eq_64;
        		data->pkts127Octets 	= gdma2StatsRx.from_65_to_127;
        		data->pkts255Octets 	= gdma2StatsRx.from_128_to_255;
        		data->pkts511Octets 	= gdma2StatsRx.from_256_to_511;
        		data->pkts1023Octets	= gdma2StatsRx.from_512_to_1023;
        		data->pkts1518Octets	= gdma2StatsRx.from_1024_to_1518;
        	}
        	else{
        		if(blapi_traffic_get_wan_tx_statistics(&gdma2StatsTx)!= 0){
        			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d] fe_lib_get_gdma2_tx_statistics fail\n",__FUNCTION__,__LINE__);
        			return -1;
        		}
        		data->dropEvents	= gdma2StatsTx.drop_cnt;
        		data->octets		= gdma2StatsTx.frame_len;
        		data->packets		= gdma2StatsTx.frame_cnt;
        		data->broadcastPkts 	= gdma2StatsTx.broadcast;
        		data->multicastPkts 	= gdma2StatsTx.multicast;
        		data->crcErroredPkts	= 0;  //no crc
        		data->undersizePkts 	= gdma2StatsTx.less_64;
        		data->oversizePkts	= gdma2StatsTx.more_1518;
        		data->pkts64Octets	= gdma2StatsTx.eq_64;
        		data->pkts127Octets 	= gdma2StatsTx.from_65_to_127;
        		data->pkts255Octets 	= gdma2StatsTx.from_128_to_255;
        		data->pkts511Octets 	= gdma2StatsTx.from_256_to_511;
        		data->pkts1023Octets	= gdma2StatsTx.from_512_to_1023;
        		data->pkts1518Octets	= gdma2StatsTx.from_1024_to_1518;
        	}
        	return 0;
        case OMCI_CLASS_ID_PPTP_ETHERNET_UNI:
            validPortId = (ctrl_block.parent_me_instId & 0xff)-1;
            if(direction){
        	    if(getMacMT7530PortTXCnt(data, validPortId) != 0){
					return -1;
				}
        	}else{
        	    if(getMacMT7530PortRXCnt(data, validPortId) != 0){
					return -1;
				}
        	}
        	return 0;
        default:
            omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]->unknown parent class ME %d.\n",__FUNCTION__,__LINE__, ctrl_block.parent_me_classId);
            break;
    }
	
	return -1;
    
}

int get_eth_frame_extend_pm_history_data(pm_history_data_list_ptr pm_list, uint8_t syncFlag)
{
    EthFramePmStreamCounters_t eth_frame = {0};
    uint8_t onlyCurrentDataFlag = 0;

    if(pm_list == NULL)
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]  pm_list is NULL fail\n",__FUNCTION__,__LINE__);
        return -1;
    }
    
    if(get_eth_frame_extend_data(pm_list->ctrl_block, &eth_frame) != 0)
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]->get_eth_frame_extend_data fail.\n",__FUNCTION__,__LINE__);
        return -1;
    }
    
    onlyCurrentDataFlag = pm_list->ctrl_block.control_field & 0x0001;

    if(syncFlag)
    {
        if(onlyCurrentDataFlag)
        {
            pm_list->pm_data.eth_frame_ext_pm.interEndTime= pmIntervalTimes;
        	pm_list->pm_data.eth_frame_ext_pm.dropEvent= (uint32_t)eth_frame.dropEvents;
        	pm_list->pm_data.eth_frame_ext_pm.octets= (uint32_t)eth_frame.octets;
        	pm_list->pm_data.eth_frame_ext_pm.frames= (uint32_t)eth_frame.packets;
            pm_list->pm_data.eth_frame_ext_pm.broadFrames= (uint32_t)eth_frame.broadcastPkts;
            pm_list->pm_data.eth_frame_ext_pm.multiFrames= (uint32_t)eth_frame.multicastPkts;
            pm_list->pm_data.eth_frame_ext_pm.crcErrFrames= (uint32_t)eth_frame.crcErroredPkts;
        	pm_list->pm_data.eth_frame_ext_pm.underFrames= (uint32_t)eth_frame.undersizePkts;
        	pm_list->pm_data.eth_frame_ext_pm.overFrames= (uint32_t)eth_frame.oversizePkts;
            pm_list->pm_data.eth_frame_ext_pm.frames64= (uint32_t)eth_frame.pkts64Octets;
            pm_list->pm_data.eth_frame_ext_pm.frames65to127= (uint32_t)eth_frame.pkts127Octets;
            pm_list->pm_data.eth_frame_ext_pm.frames128to255= (uint32_t)eth_frame.pkts255Octets;
        	pm_list->pm_data.eth_frame_ext_pm.frames256to511= (uint32_t)eth_frame.pkts511Octets;
        	pm_list->pm_data.eth_frame_ext_pm.frames512to1023= (uint32_t)eth_frame.pkts1023Octets;
            pm_list->pm_data.eth_frame_ext_pm.frames1024to1518= (uint32_t)eth_frame.pkts1518Octets;
        }
        else
        {
            pm_list->pm_data.eth_frame_ext_pm.interEndTime= pmIntervalTimes;
        	pm_list->pm_data.eth_frame_ext_pm.dropEvent= (uint32_t)(eth_frame.dropEvents- pm_list->pm_prev_data.ethFrameExtend.dropEvents);
        	pm_list->pm_data.eth_frame_ext_pm.octets= (uint32_t)(eth_frame.octets- pm_list->pm_prev_data.ethFrameExtend.octets);
        	pm_list->pm_data.eth_frame_ext_pm.frames= (uint32_t)(eth_frame.packets- pm_list->pm_prev_data.ethFrameExtend.packets);
            pm_list->pm_data.eth_frame_ext_pm.broadFrames= (uint32_t)(eth_frame.broadcastPkts- pm_list->pm_prev_data.ethFrameExtend.broadcastPkts);
            pm_list->pm_data.eth_frame_ext_pm.multiFrames= (uint32_t)(eth_frame.multicastPkts- pm_list->pm_prev_data.ethFrameExtend.multicastPkts);
            pm_list->pm_data.eth_frame_ext_pm.crcErrFrames= (uint32_t)(eth_frame.crcErroredPkts- pm_list->pm_prev_data.ethFrameExtend.crcErroredPkts);
        	pm_list->pm_data.eth_frame_ext_pm.underFrames= (uint32_t)(eth_frame.undersizePkts- pm_list->pm_prev_data.ethFrameExtend.undersizePkts);
        	pm_list->pm_data.eth_frame_ext_pm.overFrames= (uint32_t)(eth_frame.oversizePkts- pm_list->pm_prev_data.ethFrameExtend.oversizePkts);
            pm_list->pm_data.eth_frame_ext_pm.frames64= (uint32_t)(eth_frame.pkts64Octets- pm_list->pm_prev_data.ethFrameExtend.pkts64Octets);
            pm_list->pm_data.eth_frame_ext_pm.frames65to127= (uint32_t)(eth_frame.pkts127Octets- pm_list->pm_prev_data.ethFrameExtend.pkts127Octets);
            pm_list->pm_data.eth_frame_ext_pm.frames128to255= (uint32_t)(eth_frame.pkts255Octets- pm_list->pm_prev_data.ethFrameExtend.pkts255Octets);
        	pm_list->pm_data.eth_frame_ext_pm.frames256to511= (uint32_t)(eth_frame.pkts511Octets- pm_list->pm_prev_data.ethFrameExtend.pkts511Octets);
        	pm_list->pm_data.eth_frame_ext_pm.frames512to1023= (uint32_t)(eth_frame.pkts1023Octets- pm_list->pm_prev_data.ethFrameExtend.pkts1023Octets);
            pm_list->pm_data.eth_frame_ext_pm.frames1024to1518= (uint32_t)(eth_frame.pkts1518Octets- pm_list->pm_prev_data.ethFrameExtend.pkts1518Octets);
        }

        omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]15min->dropEvent = 0x%x\n",__FUNCTION__,__LINE__, pm_list->pm_data.eth_frame_ext_pm.dropEvent);
    	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]15min->octets = 0x%x\n",__FUNCTION__,__LINE__, pm_list->pm_data.eth_frame_ext_pm.octets);
    	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]15min->packets = 0x%x\n",__FUNCTION__,__LINE__, pm_list->pm_data.eth_frame_ext_pm.frames);
    	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]15min->broadPackets = 0x%x\n",__FUNCTION__,__LINE__, pm_list->pm_data.eth_frame_ext_pm.broadFrames);
    	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]15min->multiPackets = 0x%x\n",__FUNCTION__,__LINE__,pm_list->pm_data.eth_frame_ext_pm.multiFrames);
    	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]15min->crcErrPackets = 0x%x\n",__FUNCTION__,__LINE__, pm_list->pm_data.eth_frame_ext_pm.crcErrFrames);
    	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]15min->underPackets = 0x%x\n",__FUNCTION__,__LINE__, pm_list->pm_data.eth_frame_ext_pm.underFrames);
    	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]15min->overPackets = 0x%x\n",__FUNCTION__,__LINE__, pm_list->pm_data.eth_frame_ext_pm.overFrames);
    	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]15min->packets64 = 0x%x\n",__FUNCTION__,__LINE__, pm_list->pm_data.eth_frame_ext_pm.frames64);
    	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]15min->packets65to127 = 0x%x\n",__FUNCTION__,__LINE__,pm_list->pm_data.eth_frame_ext_pm.frames65to127);
    	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]15min->packets128to255 = 0x%x\n",__FUNCTION__,__LINE__, pm_list->pm_data.eth_frame_ext_pm.frames128to255);
    	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]15min->packets256to511 = 0x%x\n",__FUNCTION__,__LINE__, pm_list->pm_data.eth_frame_ext_pm.frames256to511);
    	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]15min->packets512to1023 = 0x%x\n",__FUNCTION__,__LINE__, pm_list->pm_data.eth_frame_ext_pm.frames512to1023);
    	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]15min->packets1024to1518 = 0x%x\n",__FUNCTION__,__LINE__, pm_list->pm_data.eth_frame_ext_pm.frames1024to1518);
    }

    memcpy(&pm_list->pm_prev_data.ethFrameExtend, &eth_frame, sizeof(EthFramePmStreamCounters_t));

    omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->dropEvent = 0x%llx\n",__FUNCTION__,__LINE__, pm_list->pm_prev_data.ethFrameExtend.dropEvents);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->octets = 0x%llx\n",__FUNCTION__,__LINE__, pm_list->pm_prev_data.ethFrameExtend.octets);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->packets = 0x%llx\n",__FUNCTION__,__LINE__, pm_list->pm_prev_data.ethFrameExtend.packets);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->broadPackets = 0x%llx\n",__FUNCTION__,__LINE__, pm_list->pm_prev_data.ethFrameExtend.broadcastPkts);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->multiPackets = 0x%llx\n",__FUNCTION__,__LINE__,pm_list->pm_prev_data.ethFrameExtend.multicastPkts);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->crcErrPackets = 0x%llx\n",__FUNCTION__,__LINE__, pm_list->pm_prev_data.ethFrameExtend.crcErroredPkts);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->underPackets = 0x%llx\n",__FUNCTION__,__LINE__, pm_list->pm_prev_data.ethFrameExtend.undersizePkts);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->overPackets = 0x%llx\n",__FUNCTION__,__LINE__, pm_list->pm_prev_data.ethFrameExtend.oversizePkts);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->packets64 = 0x%llx\n",__FUNCTION__,__LINE__, pm_list->pm_prev_data.ethFrameExtend.pkts64Octets);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->packets65to127 = 0x%llx\n",__FUNCTION__,__LINE__,pm_list->pm_prev_data.ethFrameExtend.pkts127Octets);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->packets128to255 = 0x%llx\n",__FUNCTION__,__LINE__, pm_list->pm_prev_data.ethFrameExtend.pkts255Octets);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->packets256to511 = 0x%llx\n",__FUNCTION__,__LINE__, pm_list->pm_prev_data.ethFrameExtend.pkts511Octets);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->packets512to1023 = 0x%llx\n",__FUNCTION__,__LINE__, pm_list->pm_prev_data.ethFrameExtend.pkts1023Octets);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->packets1024to1518 = 0x%llx\n",__FUNCTION__,__LINE__, pm_list->pm_prev_data.ethFrameExtend.pkts1518Octets);
	
    return 0;
}

int omci_me_eth_frame_extend_pm_history_get_curr_op(management_entry_ptr me_entry, omci_me_info_ptr me_info)
{
    omci_eth_frame_ext_pm_ptr eth_frame_ext_pm_new = NULL;
    EthFramePmStreamCounters_t eth_frame = {0};
    extend_pm_ctrl_block_t ctrl_block = {0};

    if(me_entry == NULL || me_info == NULL)
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]pointer is NULL.\n",__FUNCTION__,__LINE__);
        return -1;
    }

    if(omci_attr_get_old_data_except_table_attr(me_info) != 0)
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]get data failed.\n",__FUNCTION__,__LINE__);
		return -1;
    }

    eth_frame_ext_pm_new = (omci_eth_frame_ext_pm_ptr)me_info->attributes;
    if(eth_frame_ext_pm_new == NULL)
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]me info attribute is NULL.\n",__FUNCTION__,__LINE__);
        return -1;
    }

    omci_pm_parse_extend_pm_ctrl_block(&ctrl_block, me_info->attributes+3);

    if(get_eth_frame_extend_data(ctrl_block, &eth_frame) != 0)
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]->get_eth_frame_extend_data fail.\n",__FUNCTION__,__LINE__);
        return -1;
    }

	eth_frame_ext_pm_new->interEndTime= pmIntervalTimes;
	eth_frame_ext_pm_new->dropEvent= (uint32_t)eth_frame.dropEvents;
	eth_frame_ext_pm_new->octets= (uint32_t)eth_frame.octets;
	eth_frame_ext_pm_new->frames= (uint32_t)eth_frame.packets;
	eth_frame_ext_pm_new->broadFrames= (uint32_t)eth_frame.broadcastPkts;
	eth_frame_ext_pm_new->multiFrames= (uint32_t)eth_frame.multicastPkts;
	eth_frame_ext_pm_new->crcErrFrames= (uint32_t)eth_frame.crcErroredPkts;
	eth_frame_ext_pm_new->underFrames= (uint32_t)eth_frame.undersizePkts;
	eth_frame_ext_pm_new->overFrames= (uint32_t)eth_frame.oversizePkts;
	eth_frame_ext_pm_new->frames64= (uint32_t)eth_frame.pkts64Octets;
	eth_frame_ext_pm_new->frames65to127= (uint32_t)eth_frame.pkts127Octets;
	eth_frame_ext_pm_new->frames128to255= (uint32_t)eth_frame.pkts255Octets;
	eth_frame_ext_pm_new->frames256to511= (uint32_t)eth_frame.pkts511Octets;
	eth_frame_ext_pm_new->frames512to1023= (uint32_t)eth_frame.pkts1023Octets;
	eth_frame_ext_pm_new->frames1024to1518= (uint32_t)eth_frame.pkts1518Octets;
	

	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->dropEvent = 0x%x\n",__FUNCTION__,__LINE__, eth_frame_ext_pm_new->dropEvent);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->octets = 0x%x\n",__FUNCTION__,__LINE__, eth_frame_ext_pm_new->octets);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->packets = 0x%x\n",__FUNCTION__,__LINE__, eth_frame_ext_pm_new->frames);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->broadPackets = 0x%x\n",__FUNCTION__,__LINE__, eth_frame_ext_pm_new->broadFrames);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->multiPackets = 0x%x\n",__FUNCTION__,__LINE__,eth_frame_ext_pm_new->multiFrames);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->crcErrPackets = 0x%x\n",__FUNCTION__,__LINE__, eth_frame_ext_pm_new->crcErrFrames);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->underPackets = 0x%x\n",__FUNCTION__,__LINE__, eth_frame_ext_pm_new->underFrames);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->overPackets = 0x%x\n",__FUNCTION__,__LINE__, eth_frame_ext_pm_new->overFrames);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->packets64 = 0x%x\n",__FUNCTION__,__LINE__, eth_frame_ext_pm_new->frames64);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->packets65to127 = 0x%x\n",__FUNCTION__,__LINE__,eth_frame_ext_pm_new->frames65to127);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->packets128to255 = 0x%x\n",__FUNCTION__,__LINE__, eth_frame_ext_pm_new->frames128to255);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->packets256to511 = 0x%x\n",__FUNCTION__,__LINE__, eth_frame_ext_pm_new->frames256to511);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->packets512to1023 = 0x%x\n",__FUNCTION__,__LINE__, eth_frame_ext_pm_new->frames512to1023);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->packets1024to1518 = 0x%x\n",__FUNCTION__,__LINE__, eth_frame_ext_pm_new->frames1024to1518);

    return 0;
}


int omci_me_eth_frame_extend_pm_history_notify(pm_history_data_list_ptr pm_list, omci_me_info_t threshold_info)
{
    enum{ ETH_FRAME_UP_PM_HISTORY_DATA_TCA_NUM = 4};
    omci_threshold_data_1_ptr threshold_data1 = NULL;
    int i = 0;
    uint32_t currentData[ETH_FRAME_UP_PM_HISTORY_DATA_TCA_NUM] = {0};
    static uint8_t reportFlag[ETH_FRAME_UP_PM_HISTORY_DATA_TCA_NUM] = {0};
    uint8_t alarm_num[ETH_FRAME_UP_PM_HISTORY_DATA_TCA_NUM] = {1, 2, 3, 4};
    tca_notify_info_t tca_info = {0};
    EthFramePmStreamCounters_t eth_frame = {0};
    uint8_t global_clear = 0;
    
    if(pm_list == NULL)
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]  pm_list is NULL fail\n",__FUNCTION__,__LINE__);
        return -1;
    }
    if(omci_pm_is_end_of_interval_time())
    {
        memset(reportFlag, 0, sizeof(reportFlag));
        return 0;
    }
    if(threshold_info.class_id != OMCI_CLASS_ID_THRESHOLD_DATA1){
        return 0;
    }

	threshold_data1 =  (omci_threshold_data_1_ptr)threshold_info.attributes;
	if(threshold_data1 == NULL)
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]  threshold value is NULL \n",__FUNCTION__,__LINE__);
        return -1;
    }
    if(get_eth_frame_extend_data(pm_list->ctrl_block, &eth_frame) != 0)
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]->get_eth_frame_extend_data fail.\n",__FUNCTION__,__LINE__);
        return -1;
    }
    /*monitor 15min interval tca attribute value*/
	currentData[0]= (uint32_t)(eth_frame.dropEvents - pm_list->pm_prev_data.ethFrameExtend.dropEvents);
	currentData[1]= (uint32_t)(eth_frame.crcErroredPkts - pm_list->pm_prev_data.ethFrameExtend.crcErroredPkts);
	currentData[2]= (uint32_t)(eth_frame.undersizePkts - pm_list->pm_prev_data.ethFrameExtend.undersizePkts);
	currentData[3]= (uint32_t)(eth_frame.oversizePkts - pm_list->pm_prev_data.ethFrameExtend.oversizePkts); 

	global_clear = (pm_list->ctrl_block.accumulation_disable & 0x8000) >> 15;

    for(i = 0; i < ETH_FRAME_UP_PM_HISTORY_DATA_TCA_NUM; i++)
    {
        if(pm_list->ctrl_block.tca_disable & 0x4000) //global disable all tca
        {
            omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN, "[%s][%d]->glabal disable tca.\n",__FUNCTION__,__LINE__);
            break;
        }
        if((pm_list->ctrl_block.tca_disable >> i) & 0x1) //disable the tca by treshold value
        {
            omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN, "[%s][%d]->disable tca threshold value [%d].\n",__FUNCTION__,__LINE__, i+1);
            continue;
        }
        tca_info.classId = pm_list->classId;
        tca_info.instId = pm_list->instId;
        tca_info.currentData = currentData[i];
        tca_info.threshold = threshold_data1->thresholdValue[i];
        tca_info.alarm_num = alarm_num[i];
        tca_info.reportFlag = reportFlag[i];

        reportFlag[i] = omci_pm_report_alarm_by_tca_info(tca_info, global_clear);
	}

	return 0;
    
}

omci_me_func_t omci_me_eth_frame_ext_pm_op ={
    omci_me_general_pm_history_create_del_op,
    omci_me_general_pm_history_create_del_op,
    omci_me_general_pm_history_set_op,
    omci_me_general_pm_history_get_op,
    omci_me_eth_frame_extend_pm_history_get_curr_op,
};

omci_eth_frame_ext_pm_t omci_eth_frame_ext_pm_attr_data = {0};

omci_attr_t omci_eth_frame_ext_pm_attr ={
	(uint8_t *)&omci_eth_frame_ext_pm_attr_data,
	sizeof(omci_eth_frame_ext_pm_attr_data)
};


/*******************************************************************************************************************************
9.3.33 MAC bridge port ICMPv6 process preassign table

********************************************************************************************************************************/

omci_attr_dscp_t omci_attr_mac_br_port_icmpv6_proc_pre_tbl_op[]={
{0, "meId",						2,  ATTR_ACCESS_R,      ATTR_FORMAT_UNSIGNED_INT,   ATTR_FULLY_SUPPORT,&generalAttrFunc},
{1, "icmpv6 error msg",			1,  ATTR_ACCESS_R_W,    ATTR_FORMAT_BIT_FIELD,      ATTR_FULLY_SUPPORT,&generalAttrFunc},
{2, "icmpv6 informational msg",	1,  ATTR_ACCESS_R_W,    ATTR_FORMAT_BIT_FIELD,      ATTR_FULLY_SUPPORT,&generalAttrFunc},
{3, "router solicitation",		1,  ATTR_ACCESS_R_W,    ATTR_FORMAT_BIT_FIELD,      ATTR_FULLY_SUPPORT,&generalAttrFunc},
{4, "router advertisement",		1,  ATTR_ACCESS_R_W,    ATTR_FORMAT_BIT_FIELD,      ATTR_FULLY_SUPPORT,&generalAttrFunc},
{5, "neighbor solicitation",	1,  ATTR_ACCESS_R_W,    ATTR_FORMAT_BIT_FIELD,      ATTR_FULLY_SUPPORT,&generalAttrFunc},
{6, "neighbor advertisement",	1,  ATTR_ACCESS_R_W,    ATTR_FORMAT_BIT_FIELD,      ATTR_FULLY_SUPPORT,&generalAttrFunc},
{7, "redirect",					1,  ATTR_ACCESS_R_W,    ATTR_FORMAT_BIT_FIELD,      ATTR_FULLY_SUPPORT,&generalAttrFunc},
{8, "multicast listener query",	1,  ATTR_ACCESS_R_W,    ATTR_FORMAT_BIT_FIELD,      ATTR_FULLY_SUPPORT,&generalAttrFunc},
{9, "unknown icmpv6",			1,  ATTR_ACCESS_R_W,    ATTR_FORMAT_BIT_FIELD,      ATTR_FULLY_SUPPORT,&generalAttrFunc},
{255, "", 						0, 	0, 	0, 	0, 		NULL}
};

omci_me_func_t omci_me_mac_br_port_icmpv6_proc_pre_tbl_op ={
	omci_me_mac_br_icmpv6_proc_create_op,
	omci_me_mac_br_icmpv6_proc_delete_op,
	omci_me_mac_br_icmpv6_proc_set_op,
	omci_me_general_get_op
};

omci_mac_br_port_icmpv6_proc_pre_tbl_t omci_mac_br_port_icmpv6_proc_pre_tbl_attr_data = {0};

omci_attr_t omci_mac_br_port_icmpv6_proc_pre_tbl_attr ={
	(uint8_t *)&omci_mac_br_port_icmpv6_proc_pre_tbl_attr_data,
	sizeof(omci_mac_br_port_icmpv6_proc_pre_tbl_attr_data)
};

/*******************************************************************************************************************************
9.3.34 Ethernet frame extended pm 64-bit

********************************************************************************************************************************/
omci_attr_dscp_t omci_attr_eth_frame_ext_pm_64bit_op[]={
{0, "meId", 					    2,  ATTR_ACCESS_R_SET_CREATE,       ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT, &generalAttrFunc},
{1, "interval end time",		    1,  ATTR_ACCESS_R,                  ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT, &generalAttrFunc},
{2, "control block",			    16, ATTR_ACCESS_R_W_SET_CREATE,     ATTR_FORMAT_STRING,   		 ATTR_FULLY_SUPPORT, &generalAttrFunc},
{3, "drop events",					8,  ATTR_ACCESS_R,                  ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT, &generalAttrFunc},
{4, "octets",						8,  ATTR_ACCESS_R,                  ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT, &generalAttrFunc},
{5, "frames",						8,  ATTR_ACCESS_R,                  ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT, &generalAttrFunc},
{6, "broadcast frames",				8,  ATTR_ACCESS_R,                  ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT, &generalAttrFunc},
{7, "multicast frames",				8,  ATTR_ACCESS_R,                  ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT, &generalAttrFunc},
{8, "CRC errored frames",			8,  ATTR_ACCESS_R,                  ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT, &generalAttrFunc},
{9, "undersize frames",				8,  ATTR_ACCESS_R,                  ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT, &generalAttrFunc},
{10, "oversize frames", 			8,  ATTR_ACCESS_R,                  ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT, &generalAttrFunc},
{11, "frames 64 octets",			8,  ATTR_ACCESS_R,                  ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT, &generalAttrFunc},
{12, "frames 65 to 127 octets",		8,  ATTR_ACCESS_R,                  ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT, &generalAttrFunc},
{13, "frames 128 to 255 octets",	8,  ATTR_ACCESS_R,                  ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT, &generalAttrFunc},
{14, "frames 256 to 511 octets",	8,  ATTR_ACCESS_R,                  ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT, &generalAttrFunc},
{15, "frames 512 to 1023 octets",	8,  ATTR_ACCESS_R,                  ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT, &generalAttrFunc},
{16, "frames 1024 to 1518 octets",  8,  ATTR_ACCESS_R,                  ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT, &generalAttrFunc},
{255, "", 							0, 	0, 	0, 	0, 	 NULL}
};

int get_eth_frame_extend_64bit_pm_history_data(pm_history_data_list_ptr pm_list, uint8_t syncFlag)
{
    EthFramePmStreamCounters_t eth_frame = {0};
    uint8_t onlyCurrentDataFlag = 0;

    if(pm_list == NULL)
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]  pm_list is NULL fail\n",__FUNCTION__,__LINE__);
        return -1;
    }
    
    if(get_eth_frame_extend_data(pm_list->ctrl_block, &eth_frame) != 0)
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]->get_eth_frame_extend_data fail.\n",__FUNCTION__,__LINE__);
        return -1;
    }
    
    onlyCurrentDataFlag = pm_list->ctrl_block.control_field & 0x0001;

    if(syncFlag)
    {
        if(onlyCurrentDataFlag)
        {
            pm_list->pm_data.eth_frame_ext_64bit_pm.interEndTime= pmIntervalTimes;
        	pm_list->pm_data.eth_frame_ext_64bit_pm.dropEvent= eth_frame.dropEvents;
        	pm_list->pm_data.eth_frame_ext_64bit_pm.octets= eth_frame.octets;
        	pm_list->pm_data.eth_frame_ext_64bit_pm.frames= eth_frame.packets;
            pm_list->pm_data.eth_frame_ext_64bit_pm.broadFrames= eth_frame.broadcastPkts;
            pm_list->pm_data.eth_frame_ext_64bit_pm.multiFrames= eth_frame.multicastPkts;
            pm_list->pm_data.eth_frame_ext_64bit_pm.crcErrFrames= eth_frame.crcErroredPkts;
        	pm_list->pm_data.eth_frame_ext_64bit_pm.underFrames= eth_frame.undersizePkts;
        	pm_list->pm_data.eth_frame_ext_64bit_pm.overFrames= eth_frame.oversizePkts;
            pm_list->pm_data.eth_frame_ext_64bit_pm.frames64= eth_frame.pkts64Octets;
            pm_list->pm_data.eth_frame_ext_64bit_pm.frames65to127= eth_frame.pkts127Octets;
            pm_list->pm_data.eth_frame_ext_64bit_pm.frames128to255= eth_frame.pkts255Octets;
        	pm_list->pm_data.eth_frame_ext_64bit_pm.frames256to511= eth_frame.pkts511Octets;
        	pm_list->pm_data.eth_frame_ext_64bit_pm.frames512to1023= eth_frame.pkts1023Octets;
            pm_list->pm_data.eth_frame_ext_64bit_pm.frames1024to1518= eth_frame.pkts1518Octets;
        }
        else
        {
            pm_list->pm_data.eth_frame_ext_64bit_pm.interEndTime= pmIntervalTimes;
        	pm_list->pm_data.eth_frame_ext_64bit_pm.dropEvent= eth_frame.dropEvents- pm_list->pm_prev_data.ethFrameExtend.dropEvents;
        	pm_list->pm_data.eth_frame_ext_64bit_pm.octets= eth_frame.octets- pm_list->pm_prev_data.ethFrameExtend.octets;
        	pm_list->pm_data.eth_frame_ext_64bit_pm.frames= eth_frame.packets- pm_list->pm_prev_data.ethFrameExtend.packets;
            pm_list->pm_data.eth_frame_ext_64bit_pm.broadFrames= eth_frame.broadcastPkts- pm_list->pm_prev_data.ethFrameExtend.broadcastPkts;
            pm_list->pm_data.eth_frame_ext_64bit_pm.multiFrames= eth_frame.multicastPkts- pm_list->pm_prev_data.ethFrameExtend.multicastPkts;
            pm_list->pm_data.eth_frame_ext_64bit_pm.crcErrFrames= eth_frame.crcErroredPkts- pm_list->pm_prev_data.ethFrameExtend.crcErroredPkts;
        	pm_list->pm_data.eth_frame_ext_64bit_pm.underFrames= eth_frame.undersizePkts- pm_list->pm_prev_data.ethFrameExtend.undersizePkts;
        	pm_list->pm_data.eth_frame_ext_64bit_pm.overFrames= eth_frame.oversizePkts- pm_list->pm_prev_data.ethFrameExtend.oversizePkts;
            pm_list->pm_data.eth_frame_ext_64bit_pm.frames64= eth_frame.pkts64Octets- pm_list->pm_prev_data.ethFrameExtend.pkts64Octets;
            pm_list->pm_data.eth_frame_ext_64bit_pm.frames65to127= eth_frame.pkts127Octets- pm_list->pm_prev_data.ethFrameExtend.pkts127Octets;
            pm_list->pm_data.eth_frame_ext_64bit_pm.frames128to255= eth_frame.pkts255Octets- pm_list->pm_prev_data.ethFrameExtend.pkts255Octets;
        	pm_list->pm_data.eth_frame_ext_64bit_pm.frames256to511= eth_frame.pkts511Octets- pm_list->pm_prev_data.ethFrameExtend.pkts511Octets;
        	pm_list->pm_data.eth_frame_ext_64bit_pm.frames512to1023= eth_frame.pkts1023Octets- pm_list->pm_prev_data.ethFrameExtend.pkts1023Octets;
            pm_list->pm_data.eth_frame_ext_64bit_pm.frames1024to1518= eth_frame.pkts1518Octets- pm_list->pm_prev_data.ethFrameExtend.pkts1518Octets;
        }

        omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]15min->dropEvent = 0x%llx\n",__FUNCTION__,__LINE__, pm_list->pm_data.eth_frame_ext_64bit_pm.dropEvent);
    	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]15min->octets = 0x%llx\n",__FUNCTION__,__LINE__, pm_list->pm_data.eth_frame_ext_64bit_pm.octets);
    	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]15min->packets = 0x%llx\n",__FUNCTION__,__LINE__, pm_list->pm_data.eth_frame_ext_64bit_pm.frames);
    	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]15min->broadPackets = 0x%llx\n",__FUNCTION__,__LINE__, pm_list->pm_data.eth_frame_ext_64bit_pm.broadFrames);
    	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]15min->multiPackets = 0x%llx\n",__FUNCTION__,__LINE__,pm_list->pm_data.eth_frame_ext_64bit_pm.multiFrames);
    	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]15min->crcErrPackets = 0x%llx\n",__FUNCTION__,__LINE__, pm_list->pm_data.eth_frame_ext_64bit_pm.crcErrFrames);
    	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]15min->underPackets = 0x%llx\n",__FUNCTION__,__LINE__, pm_list->pm_data.eth_frame_ext_64bit_pm.underFrames);
    	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]15min->overPackets = 0x%llx\n",__FUNCTION__,__LINE__, pm_list->pm_data.eth_frame_ext_64bit_pm.overFrames);
    	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]15min->packets64 = 0x%llx\n",__FUNCTION__,__LINE__, pm_list->pm_data.eth_frame_ext_64bit_pm.frames64);
    	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]15min->packets65to127 = 0x%llx\n",__FUNCTION__,__LINE__,pm_list->pm_data.eth_frame_ext_64bit_pm.frames65to127);
    	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]15min->packets128to255 = 0x%llx\n",__FUNCTION__,__LINE__, pm_list->pm_data.eth_frame_ext_64bit_pm.frames128to255);
    	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]15min->packets256to511 = 0x%llx\n",__FUNCTION__,__LINE__, pm_list->pm_data.eth_frame_ext_64bit_pm.frames256to511);
    	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]15min->packets512to1023 = 0x%llx\n",__FUNCTION__,__LINE__, pm_list->pm_data.eth_frame_ext_64bit_pm.frames512to1023);
    	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]15min->packets1024to1518 = 0x%llx\n",__FUNCTION__,__LINE__, pm_list->pm_data.eth_frame_ext_64bit_pm.frames1024to1518);
    }

    memcpy(&pm_list->pm_prev_data.ethFrameExtend64b, &eth_frame, sizeof(EthFramePmStreamCounters_t));

    omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->dropEvent = 0x%llx\n",__FUNCTION__,__LINE__, pm_list->pm_prev_data.ethFrameExtend.dropEvents);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->octets = 0x%llx\n",__FUNCTION__,__LINE__, pm_list->pm_prev_data.ethFrameExtend.octets);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->packets = 0x%llx\n",__FUNCTION__,__LINE__, pm_list->pm_prev_data.ethFrameExtend.packets);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->broadPackets = 0x%llx\n",__FUNCTION__,__LINE__, pm_list->pm_prev_data.ethFrameExtend.broadcastPkts);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->multiPackets = 0x%llx\n",__FUNCTION__,__LINE__,pm_list->pm_prev_data.ethFrameExtend.multicastPkts);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->crcErrPackets = 0x%llx\n",__FUNCTION__,__LINE__, pm_list->pm_prev_data.ethFrameExtend.crcErroredPkts);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->underPackets = 0x%llx\n",__FUNCTION__,__LINE__, pm_list->pm_prev_data.ethFrameExtend.undersizePkts);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->overPackets = 0x%llx\n",__FUNCTION__,__LINE__, pm_list->pm_prev_data.ethFrameExtend.oversizePkts);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->packets64 = 0x%llx\n",__FUNCTION__,__LINE__, pm_list->pm_prev_data.ethFrameExtend.pkts64Octets);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->packets65to127 = 0x%llx\n",__FUNCTION__,__LINE__,pm_list->pm_prev_data.ethFrameExtend.pkts127Octets);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->packets128to255 = 0x%llx\n",__FUNCTION__,__LINE__, pm_list->pm_prev_data.ethFrameExtend.pkts255Octets);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->packets256to511 = 0x%llx\n",__FUNCTION__,__LINE__, pm_list->pm_prev_data.ethFrameExtend.pkts511Octets);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->packets512to1023 = 0x%llx\n",__FUNCTION__,__LINE__, pm_list->pm_prev_data.ethFrameExtend.pkts1023Octets);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->packets1024to1518 = 0x%llx\n",__FUNCTION__,__LINE__, pm_list->pm_prev_data.ethFrameExtend.pkts1518Octets);
	
    return 0;
}

int omci_me_eth_frame_extend_64bit_pm_history_get_curr_op(management_entry_ptr me_entry, omci_me_info_ptr me_info)
{
    omci_eth_frame_ext_pm_64bit_ptr eth_frame_ext64b_pm_new = NULL;
    EthFramePmStreamCounters_t eth_frame = {0};
    extend_pm_ctrl_block_t ctrl_block = {0};

    if(me_entry == NULL || me_info == NULL)
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]pointer is NULL.\n",__FUNCTION__,__LINE__);
        return -1;
    }

    if(omci_attr_get_old_data_except_table_attr(me_info) != 0)
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]get data failed.\n",__FUNCTION__,__LINE__);
		return -1;
    }
    eth_frame_ext64b_pm_new = (omci_eth_frame_ext_pm_64bit_ptr)me_info->attributes;
    if(eth_frame_ext64b_pm_new == NULL)
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]me info attribute is NULL.\n",__FUNCTION__,__LINE__);
        return -1;
    }

    omci_pm_parse_extend_pm_ctrl_block(&ctrl_block, me_info->attributes+3);

    if(get_eth_frame_extend_data(ctrl_block, &eth_frame) != 0)
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]->get_eth_frame_extend_data fail.\n",__FUNCTION__,__LINE__);
        return -1;
    }

	eth_frame_ext64b_pm_new->interEndTime= pmIntervalTimes;
	eth_frame_ext64b_pm_new->dropEvent= eth_frame.dropEvents;
	eth_frame_ext64b_pm_new->octets= eth_frame.octets;
	eth_frame_ext64b_pm_new->frames= eth_frame.packets;
	eth_frame_ext64b_pm_new->broadFrames= eth_frame.broadcastPkts;
	eth_frame_ext64b_pm_new->multiFrames= eth_frame.multicastPkts;
	eth_frame_ext64b_pm_new->crcErrFrames= eth_frame.crcErroredPkts;
	eth_frame_ext64b_pm_new->underFrames= eth_frame.undersizePkts;
	eth_frame_ext64b_pm_new->overFrames= eth_frame.oversizePkts;
	eth_frame_ext64b_pm_new->frames64= eth_frame.pkts64Octets;
	eth_frame_ext64b_pm_new->frames65to127= eth_frame.pkts127Octets;
	eth_frame_ext64b_pm_new->frames128to255= eth_frame.pkts255Octets;
	eth_frame_ext64b_pm_new->frames256to511= eth_frame.pkts511Octets;
	eth_frame_ext64b_pm_new->frames512to1023= eth_frame.pkts1023Octets;
	eth_frame_ext64b_pm_new->frames1024to1518= eth_frame.pkts1518Octets;
	

	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->dropEvent = 0x%llx\n",__FUNCTION__,__LINE__, eth_frame_ext64b_pm_new->dropEvent);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->octets = 0x%llx\n",__FUNCTION__,__LINE__, eth_frame_ext64b_pm_new->octets);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->packets = 0x%llx\n",__FUNCTION__,__LINE__, eth_frame_ext64b_pm_new->frames);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->broadPackets = 0x%llx\n",__FUNCTION__,__LINE__, eth_frame_ext64b_pm_new->broadFrames);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->multiPackets = 0x%llx\n",__FUNCTION__,__LINE__,eth_frame_ext64b_pm_new->multiFrames);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->crcErrPackets = 0x%llx\n",__FUNCTION__,__LINE__, eth_frame_ext64b_pm_new->crcErrFrames);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->underPackets = 0x%llx\n",__FUNCTION__,__LINE__, eth_frame_ext64b_pm_new->underFrames);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->overPackets = 0x%llx\n",__FUNCTION__,__LINE__, eth_frame_ext64b_pm_new->overFrames);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->packets64 = 0x%llx\n",__FUNCTION__,__LINE__, eth_frame_ext64b_pm_new->frames64);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->packets65to127 = 0x%llx\n",__FUNCTION__,__LINE__,eth_frame_ext64b_pm_new->frames65to127);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->packets128to255 = 0x%llx\n",__FUNCTION__,__LINE__, eth_frame_ext64b_pm_new->frames128to255);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->packets256to511 = 0x%llx\n",__FUNCTION__,__LINE__, eth_frame_ext64b_pm_new->frames256to511);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->packets512to1023 = 0x%llx\n",__FUNCTION__,__LINE__, eth_frame_ext64b_pm_new->frames512to1023);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->packets1024to1518 = 0x%llx\n",__FUNCTION__,__LINE__, eth_frame_ext64b_pm_new->frames1024to1518);

    return 0;
}

int omci_me_eth_frame_extend_64bit_pm_history_notify(pm_history_data_list_ptr pm_list, omci_me_info_t threshold_info)
{
    enum{ ETH_FRAME_UP_PM_HISTORY_DATA_TCA_NUM = 4};
    omci_threshold_data_64bit_ptr threshold_data = NULL;
    int i = 0;
    uint64_t currentData[ETH_FRAME_UP_PM_HISTORY_DATA_TCA_NUM] = {0};
    static uint8_t reportFlag[ETH_FRAME_UP_PM_HISTORY_DATA_TCA_NUM] = {0};
    uint8_t alarm_num[ETH_FRAME_UP_PM_HISTORY_DATA_TCA_NUM] = {1, 2, 3, 4};
    tca_notify_info_t tca_info = {0};
    EthFramePmStreamCounters_t eth_frame = {0};
    uint8_t global_clear = 0;
    
    if(pm_list == NULL)
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]  pm_list is NULL fail\n",__FUNCTION__,__LINE__);
        return -1;
    }
    if(omci_pm_is_end_of_interval_time())
    {
        memset(reportFlag, 0, sizeof(reportFlag));
        return 0;
    }
    if(threshold_info.class_id != OMCI_CLASS_ID_THRESHOLD_DATA_64_BIT){
        return 0;
    }
	threshold_data =  (omci_threshold_data_64bit_ptr)threshold_info.attributes;
	if(threshold_data == NULL)
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]  threshold value is NULL \n",__FUNCTION__,__LINE__);
        return -1;
    }
    if(get_eth_frame_extend_data(pm_list->ctrl_block, &eth_frame) != 0)
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]->get_eth_frame_extend_data fail.\n",__FUNCTION__,__LINE__);
        return -1;
    }
    /*monitor 15min interval tca attribute value*/
	currentData[0]= eth_frame.dropEvents - pm_list->pm_prev_data.ethFrameExtend.dropEvents;
	currentData[1] = eth_frame.crcErroredPkts - pm_list->pm_prev_data.ethFrameExtend.crcErroredPkts;
	currentData[2]= eth_frame.undersizePkts - pm_list->pm_prev_data.ethFrameExtend.undersizePkts;
	currentData[3]= eth_frame.oversizePkts - pm_list->pm_prev_data.ethFrameExtend.oversizePkts; 

	global_clear = (pm_list->ctrl_block.accumulation_disable & 0x8000) >> 15;

    for(i = 0; i < ETH_FRAME_UP_PM_HISTORY_DATA_TCA_NUM; i++)
    {
        if(pm_list->ctrl_block.tca_disable & 0x4000) //global disable all tca
        {
            omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN, "[%s][%d]->glabal disable tca.\n",__FUNCTION__,__LINE__);
            break;
        }
        if((pm_list->ctrl_block.tca_disable >> i) & 0x1) //disable the tca by treshold value
        {
            omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN, "[%s][%d]->disable tca threshold value [%d].\n",__FUNCTION__,__LINE__, i+1);
            continue;
        }
        tca_info.classId = pm_list->classId;
        tca_info.instId = pm_list->instId;
        tca_info.currentData = currentData[i];
        tca_info.threshold = threshold_data->thresholdValue[i];
        tca_info.alarm_num = alarm_num[i];
        tca_info.reportFlag = reportFlag[i];

        reportFlag[i] = omci_pm_report_alarm_by_tca_info(tca_info, global_clear);
	}

	return 0;
    
}

omci_me_func_t omci_me_eth_frame_ext_pm_64bit_op ={
	omci_me_general_pm_history_create_del_op,
    omci_me_general_pm_history_create_del_op,
    omci_me_general_pm_history_set_op,
    omci_me_general_pm_history_get_op,
    omci_me_eth_frame_extend_64bit_pm_history_get_curr_op,
};

omci_eth_frame_ext_pm_64bit_t omci_eth_frame_ext_pm_64bit_attr_data = {0};

omci_attr_t omci_eth_frame_ext_pm_64bit_attr ={
	(uint8_t *)&omci_eth_frame_ext_pm_64bit_attr_data,
	sizeof(omci_eth_frame_ext_pm_64bit_attr_data)
};


/********************************implement of attribute functions****************************/

int setDot1RateLimiterTPType(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr)
{
	omci_dot1_rate_limit_ptr dot1_rate_limit_ptr =NULL;
	
	if(me_info==NULL || me_info->attributes == NULL)
	{
		omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d] input paramter pointer is NULL\n",__FUNCTION__,__LINE__);
		return -1;
	}
	dot1_rate_limit_ptr = (omci_dot1_rate_limit_ptr)me_info->attributes;
	
	if((dot1_rate_limit_ptr->tpType != 1) && (dot1_rate_limit_ptr->tpType != 2)){
		// 1:MAC bridge service profile; 2:802.1p mapper service profile
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]: Invalid value!\n",__FUNCTION__,__LINE__);
		return -1;
	}

	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d]: return 0, tpType=%d\n",__FUNCTION__,__LINE__,dot1_rate_limit_ptr->tpType);	
	return 0;
}

#ifdef TCSUPPORT_OMCI_DOT1AG
int setDot1agMaintenanceDomainMDLevel(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr)
{
	omci_dot1ag_maint_domain_ptr dot1ag_maint_domain_ptr =NULL;
	
	if(me_info==NULL || me_info->attributes == NULL)
	{
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d] input paramter pointer is NULL\n",__FUNCTION__,__LINE__);
		return -1;
	}
	dot1ag_maint_domain_ptr = (omci_dot1ag_maint_domain_ptr)me_info->attributes;
	
	if(dot1ag_maint_domain_ptr->mdLevel > 7){
		//o-7 is valid, higher number have wider geographic scope
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]: Invalid value!\n",__FUNCTION__,__LINE__);
		return -1;
	}

	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d]: return 0, mdLevel=%d\n",__FUNCTION__,__LINE__,dot1ag_maint_domain_ptr->mdLevel);	
	return 0;
}

int setDot1agMaintenanceDomainMDNameFormat(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr)
{
	omci_dot1ag_maint_domain_ptr dot1ag_maint_domain_ptr =NULL;
	uint8_t tmpValue = 0;
	
	if(me_info==NULL || me_info->attributes == NULL)
	{
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d] input paramter pointer is NULL\n",__FUNCTION__,__LINE__);
		return -1;
	}
	dot1ag_maint_domain_ptr = (omci_dot1ag_maint_domain_ptr)me_info->attributes;
	tmpValue = dot1ag_maint_domain_ptr->mdNameFormat;
	
	if(tmpValue == 0 || (tmpValue > 4 && tmpValue != 32)){
		// 1:none, 2:DNS-like name , 3:MAC addr and UINT, 4: Character string,  32: ICC-based
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]: Invalid value!\n",__FUNCTION__,__LINE__);
		return -1;
	}

	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d]: return 0, mdNameFormat=%d\n",__FUNCTION__,__LINE__,dot1ag_maint_domain_ptr->mdNameFormat);	
	return 0;
}

int setDot1agMaintenanceDomainMHFCreation(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr)
{
	omci_dot1ag_maint_domain_ptr dot1ag_maint_domain_ptr =NULL;
	uint8_t tmpValue = 0;
	
	if(me_info==NULL || me_info->attributes == NULL)
	{
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d] input paramter pointer is NULL\n",__FUNCTION__,__LINE__);
		return -1;
	}
	dot1ag_maint_domain_ptr = (omci_dot1ag_maint_domain_ptr)me_info->attributes;

	tmpValue = dot1ag_maint_domain_ptr->mhfCreation;
	if(tmpValue==0 ||  tmpValue > 3){
		// 1:none, 2:default, 3:explicit
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]: Invalid value!\n",__FUNCTION__,__LINE__);
		return -1;
	}

	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d]: return 0, mhfCreation=%d\n",__FUNCTION__,__LINE__,dot1ag_maint_domain_ptr->mhfCreation);	
	return 0;
}

int setDot1agMaintenanceDomainSenderIDPermission(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr)
{
	omci_dot1ag_maint_domain_ptr dot1ag_maint_domain_ptr =NULL;
	uint8_t tmpValue = 0;
	
	if(me_info==NULL || me_info->attributes == NULL)
	{
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d] input paramter pointer is NULL\n",__FUNCTION__,__LINE__);
		return -1;
	}
	dot1ag_maint_domain_ptr = (omci_dot1ag_maint_domain_ptr)me_info->attributes;

	tmpValue = dot1ag_maint_domain_ptr->senderIdPermission;
	if(tmpValue == 0 || tmpValue > 4){
		// 1:none, 2:clasis, 3:manage,4:classisManage
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]: Invalid value!\n",__FUNCTION__,__LINE__);
		return -1;
	}

	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d]: return 0, senderIdPermission=%d\n",__FUNCTION__,__LINE__,dot1ag_maint_domain_ptr->senderIdPermission);	
	return 0;
}

int setDot1agMaintenanceDomainMANameFormat(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr)
{
	omci_dot1ag_maint_associat_ptr dot1ag_maint_associat_ptr =NULL;
	uint8_t tmpValue = 0;
	
	if(me_info==NULL || me_info->attributes == NULL)
	{
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d] input paramter pointer is NULL\n",__FUNCTION__,__LINE__);
		return -1;
	}
	dot1ag_maint_associat_ptr = (omci_dot1ag_maint_associat_ptr)me_info->attributes;
	tmpValue = dot1ag_maint_associat_ptr->shortMaNameFormat;

	if(tmpValue == 0 || tmpValue > 4){
		// 	1:primary VID, 2:character string, 3:2-octets integer, 4:VPN ID
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]: Invalid value!\n",__FUNCTION__,__LINE__);
		return -1;
	}

	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d]: return 0, shortMaNameFormat=%d\n",__FUNCTION__,__LINE__,dot1ag_maint_associat_ptr->shortMaNameFormat);	
	return 0;
}

int setDot1agMaintenanceAssociationMHFCreation(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr)
{
	omci_dot1ag_maint_associat_ptr dot1ag_maint_associat_ptr =NULL;
	uint8_t tmpValue = 0;
	
	if(me_info==NULL || me_info->attributes == NULL)
	{
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d] input paramter pointer is NULL\n",__FUNCTION__,__LINE__);
		return -1;
	}
	dot1ag_maint_associat_ptr = (omci_dot1ag_maint_associat_ptr)me_info->attributes;
	tmpValue = dot1ag_maint_associat_ptr->mhfCreation;

	if(tmpValue == 0 || tmpValue > 4){
		// 1:none, 2:default, 3:explicit, 4:defer
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]: Invalid value!\n",__FUNCTION__,__LINE__);
		return -1;
	}

	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d]: return 0, mhfCreation=%d\n",__FUNCTION__,__LINE__,dot1ag_maint_associat_ptr->mhfCreation);	
	return 0;
}

int setDot1agMaintenanceAssociationSenderIDPermission(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr)
{
	omci_dot1ag_maint_associat_ptr dot1ag_maint_associat_ptr =NULL;
	uint8_t tmpValue = 0;
	
	if(me_info==NULL || me_info->attributes == NULL)
	{
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d] input paramter pointer is NULL\n",__FUNCTION__,__LINE__);
		return -1;
	}
	dot1ag_maint_associat_ptr = (omci_dot1ag_maint_associat_ptr)me_info->attributes;
	tmpValue = dot1ag_maint_associat_ptr->senderIdPermission;

	if(tmpValue == 0 ||  tmpValue > 5){
		// 1:none, 2:clasis, 3:manage,4:classisManage,5:defer
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]: Invalid value!\n",__FUNCTION__,__LINE__);
		return -1;
	}

	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d]: return 0, senderIdPermission=%d\n",__FUNCTION__,__LINE__,dot1ag_maint_associat_ptr->senderIdPermission);	
	return 0;
}
#endif

int icmpv6MsgProcessForEbtables(int ifType, omci_mac_br_port_icmpv6_proc_pre_tbl_ptr icmpv6_tbl_ptr, char * ifName, int action)
{
	FILE *fp = NULL;
	char chainName[32] = {0};
	uint8_t attrIndex = 0;
	uint8_t tmpValue = 0;
	uint8_t *attributeValuePtr = NULL;
	int i = 0;
	int ret = 0;

	if(icmpv6_tbl_ptr == NULL)
		return -1;

	attributeValuePtr = ((uint8_t *)icmpv6_tbl_ptr + 2); // 2 byte for meId
	sprintf(chainName, "GPON_ICMPV6_EBT%d%d", ifType, icmpv6_tbl_ptr->meId);
	fp = fopen(GPON_ICMPV6_SH_EBT, "w+");
	if(fp== NULL){
		return -1;
	}
	if(action == ADD_EBT_CHAIN_FOR_GPON_ICMPV6)
	{
		fprintf(fp, "ebtables -t filter -F %s 2>/dev/null\n", chainName);
		fprintf(fp, "ebtables -t filter -D FORWARD -p IPv6 --ip6-proto 58 -j %s 2>/dev/null\n", chainName);
		fprintf(fp, "ebtables -t filter -X %s 2>/dev/null\n", chainName);
		
		fprintf(fp, "ebtables -t filter -N %s\n", chainName);
		fprintf(fp, "ebtables -t filter -A FORWARD -p IPv6 --ip6-proto 58 -j %s\n", chainName);
		fprintf(fp,"ebtables -t filter -F %s 2>/dev/null\n", chainName);
		fclose(fp);
		if(chmod(GPON_ICMPV6_SH_EBT ,777))
			return -1;
		system(GPON_ICMPV6_SH_EBT);
		unlink(GPON_ICMPV6_SH_EBT);
		return 0;
	}
	else if(action == DEL_EBT_CHAIN_FOR_GPON_ICMPV6)
	{
		fprintf(fp, "ebtables -t filter -F %s 2>/dev/null\n", chainName);
		fprintf(fp, "ebtables -t filter -D FORWARD -p IPv6 --ip6-proto 58 -j %s\n", chainName);
		fprintf(fp, "ebtables -t filter -X %s 2>/dev/null\n", chainName);
		fclose(fp);
		if(chmod(GPON_ICMPV6_SH_EBT ,777))
			return -1;
		system(GPON_ICMPV6_SH_EBT);
		unlink(GPON_ICMPV6_SH_EBT);
		return 0;
	}
	else if(action ==	UPDATE_RULE_FOR_GPON_ICMPV6)
	{
		fprintf(fp,"ebtables -t filter -F %s 2>/dev/null\n", chainName);
		for(attrIndex = 1; attrIndex<10; attrIndex++)
		{
			/*get setting for icmpv6 types*/
			tmpValue =  (*attributeValuePtr)&0x0F;
			
			/*
			* bit			name			setting
			* 1-2(LSB)		upstream		00:forward
											01:discard
											10:snoop
			* 3-4			downstream	00:forward
											01:discard
											10:snoop
			* 5-8			Reserved		0
			*/
			if(attrIndex == ICMPV6_ERROR_MSG_ATTR){
				//process upstream
				if((tmpValue&0x03) == 0){//upstream:forward
					if(ifType == LAN_INTERFACE){
						for(i=1; i<5; i++)
							fprintf(fp, "ebtables -t filter -A %s -i %s -p IPv6 --ip6-proto 58 --ip6-icmpv6type %d -j ACCEPT\n", chainName, ifName, i);
					}else{
						for(i=1; i<5; i++)
							fprintf(fp, "ebtables -t filter -A %s -o %s -p IPv6 --ip6-proto 58 --ip6-icmpv6type %d -j ACCEPT\n", chainName, ifName, i);
					}
				}else if((tmpValue&0x03) == 1){//upstream:discard
					if(ifType == LAN_INTERFACE){
						for(i=1; i<5; i++)
							fprintf(fp, "ebtables -t filter -A %s -i %s -p IPv6 --ip6-proto 58 --ip6-icmpv6type %d -j DROP\n", chainName, ifName, i);
					}else{
						for(i=1; i<5; i++)
							fprintf(fp, "ebtables -t filter -A %s -o %s -p IPv6 --ip6-proto 58 --ip6-icmpv6type %d -j DROP\n", chainName, ifName, i);
					}
				}else if((tmpValue&0x03) == 2){//upstream:snoop
					;
				}
				else{
					omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "\r\n invalid value \r\n");
					ret = -1;
				}

				//process downstream
				if((tmpValue&0x0c)>>2 == 0){//downstream:forward
					if(ifType == LAN_INTERFACE){
						for(i=1; i<5; i++)
							fprintf(fp, "ebtables -t filter -A %s -o %s -p IPv6 --ip6-proto 58 --ip6-icmpv6type %d -j ACCEPT\n", chainName, ifName, i);
					}else{
						for(i=1; i<5; i++)
							fprintf(fp, "ebtables -t filter -A %s -i %s -p IPv6 --ip6-proto 58 --ip6-icmpv6type %d -j ACCEPT\n", chainName, ifName, i);
					}
				}else if((tmpValue&0x0c)>>2 == 1){//downstream:discard
					if(ifType == LAN_INTERFACE){
						for(i=1; i<5; i++)
							fprintf(fp, "ebtables -t filter -A %s -o %s -p IPv6 --ip6-proto 58 --ip6-icmpv6type %d -j DROP\n", chainName, ifName, i);
					}else{
						for(i=1; i<5; i++)
							fprintf(fp, "ebtables -t filter -A %s -i %s -p IPv6 --ip6-proto 58 --ip6-icmpv6type %d -j DROP\n", chainName, ifName, i);
					}
				}else if((tmpValue&0x0c)>>2 == 2){//downstream:snoop
					;
				}
				else{
					omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "\r\n invalid value \r\n");
					ret = -1;
				}
			}
			else if(attrIndex == ICMPV6_INFO_MSG_ATTR){
				//process upstream
				if((tmpValue&0x03) == 0){//upstream:forward
					if(ifType == LAN_INTERFACE){
						fprintf(fp, "ebtables -t filter -A %s -i %s -p IPv6 --ip6-proto 58 --ip6-icmpv6type 128 -j ACCEPT\n", chainName, ifName);
						fprintf(fp, "ebtables -t filter -A %s -i %s -p IPv6 --ip6-proto 58 --ip6-icmpv6type 129 -j ACCEPT\n", chainName, ifName);
					}else{
						fprintf(fp, "ebtables -t filter -A %s -o %s -p IPv6 --ip6-proto 58 --ip6-icmpv6type 128 -j ACCEPT\n", chainName, ifName);
						fprintf(fp, "ebtables -t filter -A %s -o %s -p IPv6 --ip6-proto 58 --ip6-icmpv6type 129 -j ACCEPT\n", chainName, ifName);
					}
				}else if((tmpValue&0x03) == 1){//upstream:disard
					if(ifType == LAN_INTERFACE){
						fprintf(fp, "ebtables -t filter -A %s -i %s -p IPv6 --ip6-proto 58 --ip6-icmpv6type 128 -j DROP\n", chainName, ifName);
						fprintf(fp, "ebtables -t filter -A %s -i %s -p IPv6 --ip6-proto 58 --ip6-icmpv6type 129 -j DROP\n", chainName, ifName);
					}else{
						fprintf(fp, "ebtables -t filter -A %s -o %s -p IPv6 --ip6-proto 58 --ip6-icmpv6type 128 -j DROP\n", chainName, ifName);
						fprintf(fp, "ebtables -t filter -A %s -o %s -p IPv6 --ip6-proto 58 --ip6-icmpv6type 129 -j DROP\n", chainName, ifName);
					}
				}else if((tmpValue&0x03) == 2){//upstream:snoop
					;
				}else{
					omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "\r\n invalid value \r\n");
					ret = -1;
				}

				//process downstream
				if((tmpValue&0x0c)>>2 == 0){//downstream:forward
					if(ifType == LAN_INTERFACE){
						fprintf(fp, "ebtables -t filter -A %s -o %s -p IPv6 --ip6-proto 58 --ip6-icmpv6type 128 -j ACCEPT\n", chainName, ifName);
						fprintf(fp, "ebtables -t filter -A %s -o %s -p IPv6 --ip6-proto 58 --ip6-icmpv6type 129 -j ACCEPT\n", chainName, ifName);
					}else{
						fprintf(fp, "ebtables -t filter -A %s -i %s -p IPv6 --ip6-proto 58 --ip6-icmpv6type 128 -j ACCEPT\n", chainName, ifName);
						fprintf(fp, "ebtables -t filter -A %s -i %s -p IPv6 --ip6-proto 58 --ip6-icmpv6type 129 -j ACCEPT\n", chainName, ifName);
					}
				}else if((tmpValue&0x0c)>>2 == 1){//downstream:disard
					if(ifType == LAN_INTERFACE){
						fprintf(fp, "ebtables -t filter -A %s -o %s -p IPv6 --ip6-proto 58 --ip6-icmpv6type 128 -j DROP\n", chainName, ifName);
						fprintf(fp, "ebtables -t filter -A %s -o %s -p IPv6 --ip6-proto 58 --ip6-icmpv6type 129 -j DROP\n", chainName, ifName);
					}else{
						fprintf(fp, "ebtables -t filter -A %s -i %s -p IPv6 --ip6-proto 58 --ip6-icmpv6type 128 -j DROP\n", chainName, ifName);
						fprintf(fp, "ebtables -t filter -A %s -i %s -p IPv6 --ip6-proto 58 --ip6-icmpv6type 129 -j DROP\n", chainName, ifName);
					}
				}else if((tmpValue&0x0c)>>2 == 2){//downstream:snoop
					;
				}else{
					omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "\r\n invalid value \r\n");
					ret = -1;
				}
			}
			else if((attrIndex >= ICMPV6_RS_MSG_ATTR) && (attrIndex <= ICMPV6_MLD_MSG_ATTR)){
				//process upstream
				if((tmpValue&0x03) == 0){//upstream:forward
					if(ifType == LAN_INTERFACE){
						fprintf(fp, "ebtables -t filter -A %s -i %s -p IPv6 --ip6-proto 58 --ip6-icmpv6type %d -j ACCEPT\n", chainName, ifName, icmpv6Type[attrIndex-3]);
					}else{
						fprintf(fp, "ebtables -t filter -A %s -o %s -p IPv6 --ip6-proto 58 --ip6-icmpv6type %d -j ACCEPT\n", chainName, ifName, icmpv6Type[attrIndex-3]);
					}
				}else if((tmpValue&0x03) == 1){//upstream:discard
					if(ifType == LAN_INTERFACE){
						fprintf(fp, "ebtables -t filter -A %s -i %s -p IPv6 --ip6-proto 58 --ip6-icmpv6type %d -j DROP\n", chainName, ifName, icmpv6Type[attrIndex-3]);
					}else{
						fprintf(fp, "ebtables -t filter -A %s -o %s -p IPv6 --ip6-proto 58 --ip6-icmpv6type %d -j DROP\n", chainName, ifName, icmpv6Type[attrIndex-3]);
					}
				}else if((tmpValue&0x03) == 2){//upstream:snoop
					;
				}else{
					omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "\r\n invalid value \r\n");
					ret = -1;
				}

				//process downstream
				if((tmpValue&0x0c)>>2 == 0){//downstream:forward
					if(ifType == LAN_INTERFACE)
						fprintf(fp, "ebtables -t filter -A %s -o %s -p IPv6 --ip6-proto 58 --ip6-icmpv6type %d -j ACCEPT\n", chainName, ifName, icmpv6Type[attrIndex-3]);
					else
						fprintf(fp, "ebtables -t filter -A %s -i %s -p IPv6 --ip6-proto 58 --ip6-icmpv6type %d -j ACCEPT\n", chainName, ifName, icmpv6Type[attrIndex-3]);
				}else if((tmpValue&0x0c)>>2 == 1){//downstream:discard
					if(ifType == LAN_INTERFACE)
						fprintf(fp, "ebtables -t filter -A %s -o %s -p IPv6 --ip6-proto 58 --ip6-icmpv6type %d -j DROP\n", chainName, ifName, icmpv6Type[attrIndex-3]);
					else
						fprintf(fp, "ebtables -t filter -A %s -i %s -p IPv6 --ip6-proto 58 --ip6-icmpv6type %d -j DROP\n", chainName, ifName, icmpv6Type[attrIndex-3]);
				}else if((tmpValue&0x0c)>>2 == 2){//downstream:snoop
					;
				}else{
					omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "\r\n invalid value \r\n");
					ret = -1;
				}
			}
			else{// if(attrIndex == ICMPV6_UNKNOWN_MSG_ATTR){
				//process upstream
				if((tmpValue&0x03) == 0){//upstream:forward
					if(ifType == LAN_INTERFACE)
						fprintf(fp, "ebtables -t filter -A %s -i %s -p IPv6 --ip6-proto 58 -j ACCEPT\n", chainName, ifName);
					else
						fprintf(fp, "ebtables -t filter -A %s -o %s -p IPv6 --ip6-proto 58 -j ACCEPT\n", chainName, ifName);
				}else if((tmpValue&0x03) == 1){//upstream:discard
					if(ifType == LAN_INTERFACE)
						fprintf(fp, "ebtables -t filter -A %s -i %s -p IPv6 --ip6-proto 58 -j DROP\n", chainName, ifName);
					else
						fprintf(fp, "ebtables -t filter -A %s -o %s -p IPv6 --ip6-proto 58 -j DROP\n", chainName, ifName);
				}else if((tmpValue&0x03) == 2){//upstream:snoop
					;
				}else{
					omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "\r\n invalid value \r\n");
					ret = -1;
				}

				//process downsream
				if((tmpValue&0x0c)>>2 == 0){//downsream:forward
					if(ifType == LAN_INTERFACE)
						fprintf(fp, "ebtables -t filter -A %s -o %s -p IPv6 --ip6-proto 58 -j ACCEPT\n", chainName, ifName);
					else
						fprintf(fp, "ebtables -t filter -A %s -i %s -p IPv6 --ip6-proto 58 -j ACCEPT\n", chainName, ifName);
				}else if((tmpValue&0x0c)>>2 == 1){//downsream:discard
					if(ifType == LAN_INTERFACE)
						fprintf(fp, "ebtables -t filter -A %s -o %s -p IPv6 --ip6-proto 58 -j DROP\n", chainName, ifName);
					else
						fprintf(fp, "ebtables -t filter -A %s -i %s -p IPv6 --ip6-proto 58 -j DROP\n", chainName, ifName);
				}else if((tmpValue&0x0c)>>2 == 2){//downsream:snoop
					;
				}else{
					omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "\r\n invalid value \r\n");
					ret = -1;
				}
			}
			
			attributeValuePtr++; //next attribute, all attribute size ( except for meId)are equal to  1 byte;
		}
		fclose(fp);
		if(chmod(GPON_ICMPV6_SH_EBT ,777))
			return -1;
		system(GPON_ICMPV6_SH_EBT);
		unlink(GPON_ICMPV6_SH_EBT);
		return ret;
	}
	fclose(fp);
	return 0;
}

int updateRulesForGPONICMPv6(omci_mac_br_port_icmpv6_proc_pre_tbl_ptr icmpv6_tbl_ptr, int action)
{
	int ifType = 0;//0: Lan interface; 1: Wan interface
	char ifName[16] = {0};
	uint8_t ifcType = 0;
	int ret = 0;
	
	if(icmpv6_tbl_ptr == NULL)
		return -1;
	
	//get interface type, and ifName, from  MAC bridge port
	memset(ifName, 0, sizeof(ifName));
	ifType = getMacBridgePortInstType(icmpv6_tbl_ptr->meId,&ifcType);	//from Wayne
	if(ifType == 0){//LAN interface
		//get lan portid
		ret = getMacBridgePortIfcByInst(icmpv6_tbl_ptr->meId, ifName);
		if(ret != 0)
			return -1;
	}else if(ifType == 1){//WAN interface
		//get ANI portid	
		ret = getMacBridgePortIfcByInst(icmpv6_tbl_ptr->meId, ifName);//from Wayne
		if(ret != 0)
			return -1;
	}else{		
		return -1;	
	}	

	if(icmpv6MsgProcessForEbtables(ifType, icmpv6_tbl_ptr, ifName, action) != 0)
		return -1;

	return 0;
}

int omci_me_mac_br_icmpv6_proc_create_op(management_entry_ptr me_entry, omci_me_info_ptr me_info)
{
	omci_mac_br_port_icmpv6_proc_pre_tbl_ptr mac_br_port_icmpv6_proc_pre_tbl_ptr =NULL;
	int ret=0;
	
	if(me_info==NULL || me_info->attributes == NULL)
	{
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d] input paramter pointer is NULL\n",__FUNCTION__,__LINE__);
		return -1;
	}

	mac_br_port_icmpv6_proc_pre_tbl_ptr = (omci_mac_br_port_icmpv6_proc_pre_tbl_ptr)me_info->attributes;

	/*deal with ebtables*/
	ret = updateRulesForGPONICMPv6(mac_br_port_icmpv6_proc_pre_tbl_ptr, ADD_EBT_CHAIN_FOR_GPON_ICMPV6);

	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "omciCreatActionForMACBridgePortICMPv6Process: create success\n");
	return ret;
}
int omci_me_mac_br_icmpv6_proc_delete_op(management_entry_ptr me_entry, omci_me_info_ptr me_info)
{
	omci_mac_br_port_icmpv6_proc_pre_tbl_ptr mac_br_port_icmpv6_proc_pre_tbl_ptr =NULL;
	int ret=0;
	
	if(me_info==NULL || me_info->attributes == NULL)
	{
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d] input paramter pointer is NULL\n",__FUNCTION__,__LINE__);
		return -1;
	}
	mac_br_port_icmpv6_proc_pre_tbl_ptr = (omci_mac_br_port_icmpv6_proc_pre_tbl_ptr)me_info->attributes;

	ret = updateRulesForGPONICMPv6(mac_br_port_icmpv6_proc_pre_tbl_ptr, DEL_EBT_CHAIN_FOR_GPON_ICMPV6); 
	return ret;
}

int omci_me_mac_br_icmpv6_proc_set_op(management_entry_ptr me_entry, omci_me_info_ptr me_info)
{
	return setMACBridgePortICMPv6ProcessMsg(me_info);
}

int setMACBridgePortICMPv6ProcessMsg(omci_me_info_ptr me_info)
{
	omci_mac_br_port_icmpv6_proc_pre_tbl_ptr mac_br_port_icmpv6_proc_pre_tbl_ptr =NULL;
	int ret=OMCI_GET_NO_VALUE;
	
	if(me_info==NULL || me_info->attributes == NULL)
	{
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d] input paramter pointer is NULL\n",__FUNCTION__,__LINE__);
		return -1;
	}
	mac_br_port_icmpv6_proc_pre_tbl_ptr = (omci_mac_br_port_icmpv6_proc_pre_tbl_ptr)me_info->attributes;

	/*
			* bit			name			setting
			* 1-2(LSB)		upstream		00:forward
										01:discard
										10:snoop
			* 3-4			downstream	00:forward
										01:discard
										10:snoop
			* 5-8			Reserved		0
	*/
	

	ret = updateRulesForGPONICMPv6(mac_br_port_icmpv6_proc_pre_tbl_ptr, UPDATE_RULE_FOR_GPON_ICMPV6);

	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d]: return ret=%d\n",__FUNCTION__,__LINE__,ret);	
	return ret;

}

int getEthnetFrameExtendedPM64BitFunc(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr)
{	
	//??????????
	return OMCI_GET_NO_VALUE;
}
int getEthnetFrameExtendedPM64BitcontrolblockFunc(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr)
{
	return OMCI_GET_NO_VALUE;
}

